﻿using ERP.ERPModels.WorkforceManage;
using ERP.WorkforceManage.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Microsoft.EntityFrameworkCore;

namespace ERP.WorkforceManage
{
    /// <summary>
    /// 排班计划服务
    /// </summary>
    public class SchedulingPlanService : ApplicationService, ISchedulingPlanService
    {
        private readonly IRepository<SchedulingPlan, int> _schedulingPlanRepository;

        public SchedulingPlanService(
            IRepository<SchedulingPlan, int> schedulingPlanRepository)
        {
            _schedulingPlanRepository = schedulingPlanRepository;
        }

        /// <summary>
        /// 创建排班计划
        /// </summary>
        public async Task<SchedulingPlanDto> CreateAsync(CreateSchedulingPlanDto input)
        {
            var entity = new SchedulingPlan
            {
                PlanNumber = input.PlanNumber,
                PlanName = input.PlanName,
                TeamType = input.TeamType,
                StartDate = input.StartDate,
                EndDate = input.EndDate,
                ShiftSystem = input.ShiftSystem,
                DocumentStatus = input.DocumentStatus,
                TeamIdsStr = input.TeamIds != null && input.TeamIds.Any() ? string.Join(",", input.TeamIds) : ""
            };
            
            // 根据轮班方式确定工作制和天数
            if (entity.ShiftSystem == "白班")
            {
                entity.WorkShiftSystem = "";
                entity.DayCount = null;
            }
            else
            {
                // 两班倒或三班倒
                entity.WorkShiftSystem = input.WorkShiftSystem;
                
                // 按天模式才需要天数
                if (entity.WorkShiftSystem == "按天")
                {
                    entity.DayCount = input.DayCount;
                }
                else
                {
                    entity.DayCount = null;
                }
            }

            var result = await _schedulingPlanRepository.InsertAsync(entity);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<SchedulingPlan, SchedulingPlanDto>(result);
        }

        /// <summary>
        /// 删除排班计划
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            await _schedulingPlanRepository.DeleteAsync(id);
            await CurrentUnitOfWork.SaveChangesAsync();
        }

        /// <summary>
        /// 获取排班计划详情
        /// </summary>
        public async Task<SchedulingPlanDto> GetAsync(int id)
        {
            var entity = await _schedulingPlanRepository.GetAsync(id);
            return ObjectMapper.Map<SchedulingPlan, SchedulingPlanDto>(entity);
        }

        /// <summary>
        /// 获取排班计划列表
        /// </summary>
        public async Task<PagedResultDto<SchedulingPlanDto>> GetListAsync(SchedulingPlanGetListInputDto input)
        {
            var query = await _schedulingPlanRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.PlanNumber))
            {
                query = query.Where(x => x.PlanNumber.Contains(input.PlanNumber));
            }

            if (!string.IsNullOrWhiteSpace(input.PlanName))
            {
                query = query.Where(x => x.PlanName.Contains(input.PlanName));
            }

            if (!string.IsNullOrWhiteSpace(input.TeamType))
            {
                query = query.Where(x => x.TeamType == input.TeamType);
            }

            if (input.StartDate.HasValue)
            {
                query = query.Where(x => x.StartDate >= input.StartDate.Value);
            }

            if (input.EndDate.HasValue)
            {
                query = query.Where(x => x.EndDate <= input.EndDate.Value);
            }

            // 获取总记录数
            var totalCount = await query.CountAsync();

            // 应用排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            // 应用分页
            query = query.Skip(input.SkipCount).Take(input.MaxResultCount);

            var entities = await query.ToListAsync();
            var dtos = ObjectMapper.Map<List<SchedulingPlan>, List<SchedulingPlanDto>>(entities);

            return new PagedResultDto<SchedulingPlanDto>(totalCount, dtos);
        }

        /// <summary>
        /// 更新排班计划
        /// </summary>
        public async Task<SchedulingPlanDto> UpdateAsync(int id, SchedulingPlanDto input)
        {
            var entity = await _schedulingPlanRepository.GetAsync(id);

            entity.PlanNumber = input.PlanNumber;
            entity.PlanName = input.PlanName;
            entity.TeamType = input.TeamType;
            entity.StartDate = input.StartDate;
            entity.EndDate = input.EndDate;
            entity.ShiftSystem = input.ShiftSystem;
            
            // 根据轮班方式确定工作制和天数
            if (entity.ShiftSystem == "白班")
            {
                entity.WorkShiftSystem = "";
                entity.DayCount = null;
            }
            else
            {
                // 两班倒或三班倒
                entity.WorkShiftSystem = input.WorkShiftSystem;
                
                // 按天模式才需要天数
                if (entity.WorkShiftSystem == "按天")
                {
                    entity.DayCount = input.DayCount;
                }
                else
                {
                    entity.DayCount = null;
                }
            }
            
            entity.DocumentStatus = input.DocumentStatus;
            entity.TeamIdsStr = input.TeamIds != null && input.TeamIds.Any() ? string.Join(",", input.TeamIds) : "";

            await _schedulingPlanRepository.UpdateAsync(entity);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<SchedulingPlan, SchedulingPlanDto>(entity);
        }

        public async Task BatchDeleteAsync(List<int> ids)
        {
            await _schedulingPlanRepository.DeleteAsync(x => ids.Contains(x.Id));
        }
    }
}
